package com.example.ezexcel.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.ezexcel.enumerator.ServiceCode;
import com.example.ezexcel.ex.ServiceException;
import com.example.ezexcel.mapper.TopicMapper;
import com.example.ezexcel.pojo.entity.QuestionData;
import com.example.ezexcel.pojo.param.SelectParam;
import com.example.ezexcel.pojo.param.SelectTopicNumParam;
import com.example.ezexcel.pojo.param.TypeList;
import com.example.ezexcel.pojo.vo.AllDuplicateDetails;
import com.example.ezexcel.pojo.vo.DuplicateDetails;
import com.example.ezexcel.pojo.vo.FreemarkerData;
import com.example.ezexcel.pojo.vo.ValidationResult;
import com.example.ezexcel.response.JsonResult;
import com.example.ezexcel.util.FileUtils;
import com.example.ezexcel.util.Levenshtein;
import com.example.ezexcel.util.WordUtil;
import jdk.nashorn.internal.ir.annotations.Ignore;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.IntStream;

@Slf4j
@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
@RequestMapping("/topic")
public class TopicController {

    private static String resultPath = "D:/excelFile/";

    @Autowired
    private TopicMapper topicMapper;

    @CrossOrigin(origins = "*", maxAge = 3600)
    @PostMapping("/select")
    public JsonResult selectTopic(@RequestBody SelectParam selectParam, @Ignore HttpServletResponse response, @Ignore HttpServletRequest request) throws IOException, IllegalAccessException {
        log.info("selectParam:{}", selectParam);
        FreemarkerData freemarkerData = new FreemarkerData();
        freemarkerData.setTitle(selectParam.getName());
        for (TypeList typeList : selectParam.getTypeList()) {
            QueryWrapper<QuestionData> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("work_type", selectParam.getWorkType());
            queryWrapper.eq("evaluation_level", selectParam.getEvaluationLevel());
            queryWrapper.eq("question_type", typeList.getQuestionType());
            queryWrapper.eq("question_attribute", typeList.getQuestionAttribute());
            queryWrapper.eq("difficulty_level", typeList.getDifficultyLevel());
            //随机筛选selectParam.getNum()个题目
            log.info("typeList.getNum():{}", typeList.getNum());
            queryWrapper.last("ORDER BY RAND() LIMIT " + typeList.getNum());
            List<QuestionData> questionDataList = topicMapper.selectList(queryWrapper);
            System.err.println( questionDataList.size());
            convertTOFreemarkerData(freemarkerData, questionDataList, typeList.getQuestionType());
        }
        //发送word文档
        String wordName = "shijuan.ftl";
        //答案文档
        String answerName = "shijuanDan.ftl";
        //案例题文档
        String caseName = "answerAnli.ftl";
        //计算题文档
        String calculationName = "calculation.ftl";

        //出题统计文档
        String statistics = "tatistics.ftl";

        String fileName = selectParam.getName()+".docx";
        String name = "result";
        Map<String, Object> dataModel =  WordUtil.ObjectToMap(freemarkerData);
        System.err.println(dataModel);
//        log.info("dataModel:{}", dataModel);
        WordUtil.exportMillCertificateWord(request, response, dataModel, wordName, "【试题】"+fileName, name);
        WordUtil.exportMillCertificateWord(request, response, dataModel, answerName, "【通用答案】"+fileName, name);
        WordUtil.exportMillCertificateWord(request, response, dataModel, caseName, "【案例答案】"+fileName, name);
        WordUtil.exportMillCertificateWord(request, response, dataModel, calculationName, "【计算答案】"+fileName, name);
        WordUtil.exportMillCertificateWord(request, response, dataModel, statistics, "【出题统计】"+fileName, name);
        return JsonResult.ok("D:\\excelFile");
    }

    //把前端发过来的试卷数据转换成FreemarkerData
    public static void convertTOFreemarkerData (FreemarkerData freemarkerData, List<QuestionData> questionDataList, String questionType) {
        if (questionType.equals("单选题")) {
            WordUtil.convertSingleChoice(freemarkerData, questionDataList);
        }else if (questionType.equals("多选题")) {
            WordUtil.convertMultipleChoice(freemarkerData, questionDataList);
        }else if (questionType.equals("判断题")) {
            WordUtil.convertJudgement(freemarkerData, questionDataList);
        }else if (questionType.equals("简答题")) {
            WordUtil.convertShortAnswer(freemarkerData, questionDataList);
        }else if (questionType.equals("计算题")){
            WordUtil.convertCalculation(freemarkerData, questionDataList);
        }else if (questionType.equals("案例题")) {
            WordUtil.convertCase(freemarkerData, questionDataList);
        }

    }


    @GetMapping("/addTopic")
    public JsonResult setTopic(String fileName,@Ignore HttpServletResponse response, @Ignore HttpServletRequest request) {
        log.info("开始处理【导入题目】:{}", fileName);
        File file = new File(fileName);

        // 检查路径是否存在并且是否是一个文件
        if (!file.exists() || !file.isFile()) {
            throw new ServiceException(ServiceCode.OPERATION_FAILED, "文件不存在或不是一个有效文件");
        }
        // 检查文件是否为 .xlsx 文件
        if (!fileName.toLowerCase().endsWith(".xlsx")) {
            throw new ServiceException(ServiceCode.OPERATION_FAILED, "文件格式错误");
        }
        //库名称
        String dbName = file.getName();
        log.info("dbName:{}", dbName);
//        String fileName = "D:\\桌面\\wenjian\\bigtopic.xlsx"; // 替换为您的文件路径
        Map<String, Map<String,String>> errData  = new ConcurrentHashMap<>();
        EasyExcel.read(fileName, QuestionData.class, new AnalysisEventListener<QuestionData>() {
            @Override
            public void invoke(QuestionData data, AnalysisContext context) {

                // 遍历QuestionData的所有字段，去除字符串字段的空格
                for (Field field : QuestionData.class.getDeclaredFields()) {
                    field.setAccessible(true); // 确保可以访问私有字段
                    try {
                        if (field.get(data) instanceof String) {
                            String value = (String) field.get(data);
                            // 仅去除首尾空格
                            value = value.trim();
                            field.set(data, value);
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                //设置题库名称
                data.setQuestionBankName(dbName);
                log.info("data:{}", data);
                if (data==null||data.getQuestionType()==null) {
                    //跳过本次
                    return;
                }
                //遍历所有字段，如果有字段为空，就把题目编号加入到errData中
                processQuestionData(data, errData, topicMapper);

            }
            @SneakyThrows
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                // 所有数据解析完成后做的事情
                System.err.println(errData);
                Map<String, String> strings = errData.get(dbName);
                if (strings==null||strings.size()==0) {
                    return;
                }
                Map<String, Object> dataModel = new HashMap<>();
                dataModel.put("dbName", dbName);
                dataModel.put("errData", strings.toString());
                //出错统计word
                String statistics = "errWord.ftl";
                String fileName = "【出错】结果.docx";
                WordUtil.exportMillCertificateWord(request, response, dataModel, statistics, fileName, "result");
            }
        }).sheet().doRead();
        return JsonResult.ok("导入成功");
    }
    public void processQuestionData(QuestionData data, Map<String, Map<String,String>> errData, TopicMapper topicMapper) {
        // 检查除了id之外的所有字段是否有为空的情况
        ValidationResult dataVal = isDataVal(data);
        if (dataVal.isValid()) {
            topicMapper.insert(data);
        } else {
            if (data.getNum()!=null) {
                // 如果有字段为空，则将数据的序号加入到错误数据集中
                System.err.println(data.getNum());
                System.err.println(dataVal.getErrorMessage());
                errData.computeIfAbsent(data.getQuestionBankName(), k -> new ConcurrentHashMap<>())
                        .put(data.getNum(), dataVal.getErrorMessage());
            }

        }
    }

//    private boolean isDataVal(QuestionData data) {
//        // 检查基本字段是否为空
//        boolean basicFieldsValid = data.getQuestionBankName() != null &&
//                data.getNum() != null &&
//                data.getWorkType() != null &&
////                data.getEvaluationDimension() != null &&
//                data.getDimensionCategory() != null &&
////                data.getEvaluationCapability() != null &&
//                data.getEvaluationLevel() != null &&
//
////                data.getEvaluationModuleName() != null &&
////                data.getKnowledgeSkillPointName() != null &&
////                data.getAssessmentPoint() != null &&
//
//                data.getQuestionType() != null &&
//                data.getQuestionContent() != null &&
//                data.getQuestionAnswer() != null &&
//
////                data.getQuestionAttribute() != null &&
//
//                data.getDifficultyLevel() != null;
////                data.getReferenceSource() != null;
//        if (!basicFieldsValid) {
//            return false;
//        }
//
//        switch (data.getQuestionType()) {
//            case "单选题":
//            case "多选题":
//                return data.getQuestionOptions() != null && validateMultipleChoice(data.getQuestionOptions());
//
//            case "判断题":
//                return true;  // 仅需要检查是否为空，已在前面的条件中检查
//            case "简答题":
//                return true;  // 简答题不需要检查选项
//            case "计算题":
//                return validateCalculationQuestion(data);
//
//            case "案例题":
//                return validateCaseQuestion(data.getQuestionContent());
//
//            default:
//                return false;  // 对于未知题型，可以根据需求修改逻辑
//        }
//
//    }

    private ValidationResult isDataVal(QuestionData data) {
        // 检查基本字段是否为空
        boolean basicFieldsValid = data.getQuestionBankName() != null &&
                data.getNum() != null &&
                data.getWorkType() != null &&
                data.getDimensionCategory() != null &&
                data.getEvaluationLevel() != null &&
                data.getQuestionType() != null &&
                data.getQuestionContent() != null &&
                data.getQuestionAnswer() != null &&
                data.getDifficultyLevel() != null;

        if (!basicFieldsValid) {
            return new ValidationResult(false, "基本字段缺失");
        }

        switch (data.getQuestionType()) {
            case "单选题":
                if (data.getQuestionOptions() == null) {
                    return new ValidationResult(false, "选项缺失");
                } else if (!validateMultipleChoice(data.getQuestionOptions())) {
                    return new ValidationResult(false, "单选题题选项不足4个");
                }
                break;

            case "多选题":
                if (data.getQuestionOptions() == null) {
                    return new ValidationResult(false, "选项缺失");
                } else if (!validateMultipleChoice(data.getQuestionOptions())) {
                    return new ValidationResult(false, "多选题选项不足4个");
                }
                break;

            case "判断题":
            case "简答题":
                // 判断题和简答题不需要验证选项
                break;

            case "计算题":
                if (!validateCalculationQuestion(data)) {
                    return new ValidationResult(false, "计算试题中不存在图片地址或者图片地址不合法");
                }
                break;

            case "案例题":
                if (!validateCaseQuestion(data.getQuestionContent())) {
                    return new ValidationResult(false, "案例题试题正文的问题是否用$;$分割");
                }
                break;

            default:
                return new ValidationResult(false, "未知题型");
        }

        // 所有验证通过
        return new ValidationResult(true, "验证通过");
    }

    private boolean validateMultipleChoice(String questionOptions) {
        String[] options = questionOptions.split("\\$;\\$");
        return options.length >= 4;
    }

    private boolean validateCalculationQuestion(QuestionData data) {
        String[] contentParts = data.getQuestionContent().split("\\$;\\$");
        if (contentParts.length != 2) {
            return false;
        }
        File file = new File(contentParts[1]);
        log.info("file:{}", file);
        log.info("contentParts[1]:{}", contentParts[1]);
        return file.exists() && file.isFile() && isImageFile(file.getName());
    }

    private boolean validateCaseQuestion(String questionContent) {
        String[] contentParts = questionContent.split("\\$;\\$");
        return contentParts.length != 1;
    }

    private boolean isImageFile(String fileName) {
        String lowerCaseFileName = fileName.toLowerCase();
        return lowerCaseFileName.endsWith(".jpg") ||
                lowerCaseFileName.endsWith(".png") ||
                lowerCaseFileName.endsWith(".jpeg");
    }


    @GetMapping("/checkTopic")
    public JsonResult checkTopic(String fileName,@Ignore HttpServletResponse response, @Ignore HttpServletRequest request) {
        log.info("开始处理【查重】:{}", fileName);
        File file = new File(fileName);

        // 检查路径是否存在并且是否是一个文件
        if (!file.exists() || !file.isFile()) {
            throw new ServiceException(ServiceCode.OPERATION_FAILED, "文件不存在或不是一个有效文件");
        }
        // 检查文件是否为 .xlsx 文件
        if (!fileName.toLowerCase().endsWith(".xlsx")) {
            throw new ServiceException(ServiceCode.OPERATION_FAILED, "文件格式错误");
        }
        //库名称
        String dbName = file.getName();
        log.info("dbName:{}", dbName);
//        String fileName = "D:\\桌面\\wenjian\\bigtopic.xlsx"; // 替换为您的文件路径
        List<QuestionData> questionDataList = new ArrayList<>();
        Map<String, Set<String>> errData  = new ConcurrentHashMap<>();
        Map<String, QuestionData> map = new HashMap<>();
        EasyExcel.read(fileName, QuestionData.class, new AnalysisEventListener<QuestionData>() {
            @Override
            public void invoke(QuestionData data, AnalysisContext context) {

                // 遍历QuestionData的所有字段，去除字符串字段的空格
                for (Field field : QuestionData.class.getDeclaredFields()) {
                    field.setAccessible(true); // 确保可以访问私有字段
                    try {
                        if (field.get(data) instanceof String) {
                            String value = (String) field.get(data);
                            // 仅去除首尾空格
                            value = value.trim();
                            field.set(data, value);
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                //设置题库名称
                data.setQuestionBankName(dbName);
                log.info("data:{}", data);
                //如果存在
                map.put(data.getNum(), data);
                //遍历所有字段，如果有字段为空，就把题目编号加入到errData中
                newProcessQuestionData(data, errData, questionDataList);



            }
            @SneakyThrows
            @Override
            public void doAfterAllAnalysed(AnalysisContext context) {
                // 所有数据解析完成后做的事情
                Set<String> strings = errData.get(dbName);
                if (strings != null && strings.size()!=0) {
                    System.err.println(errData);
                    Map<String, Object> errDataModel = new HashMap<>();
                    errDataModel.put("dbName", dbName);
                    errDataModel.put("errData", strings.toString());
                    //出错统计word
                    String errsStatistics = "errWord.ftl";
                    String fileName = "【查重出错】结果.docx";

                    FileUtils.freemarkerExport(errsStatistics, errDataModel, resultPath , fileName,response);
                }

                // 所有数据解析完成后做的事情
                log.info("所有数据解析完成", questionDataList);
                Map<String, Set<String>> identicalMap100 = new ConcurrentHashMap<>(); // 100%相似度
                Map<String, Set<String>> identicalMap90 = new ConcurrentHashMap<>(); // 90%相似度
                Map<String, Set<String>> identicalMap85  = new ConcurrentHashMap<>();
                Set<Integer> checkedForIdentical = ConcurrentHashMap.newKeySet(); // 用于存储已经检查过的题干索引
                AllDuplicateDetails allDuplicateDetails = new AllDuplicateDetails();
                List<DuplicateDetails> duplicateDetailsList = new ArrayList<>();
                allDuplicateDetails.setDuplicateDetails(duplicateDetailsList);

                // 创建锁对象
                Lock lock = new ReentrantLock();

                IntStream.range(0, questionDataList.size()).parallel().forEach(i -> {
                    if (checkedForIdentical.contains(i)) return; // 如果这个题干已经标记为完全相同，则跳过

                    QuestionData questionObjectI = questionDataList.get(i);
                    if (questionObjectI != null) {
                        String questionI = questionObjectI.getQuestionContent();
                        if (questionI != null) {
                            for (int j = i + 1; j < questionDataList.size(); j++) {
                                if (checkedForIdentical.contains(j)) continue; // 跳过已经标记为完全相同的题干

                                QuestionData questionObjectJ = questionDataList.get(j);
                                if (questionObjectJ != null) {
                                    String questionJ = questionObjectJ.getQuestionContent();
                                    if (questionJ != null) {
                                        double similarity = Levenshtein.calculateSimilarity(questionI, questionJ);

                                        // 使用锁保证线程安全
                                        lock.lock();
                                        try {
                                            if (similarity == 100.0) {
                                                // 100%相似度
                                                identicalMap100.computeIfAbsent(questionI, k -> ConcurrentHashMap.newKeySet())
                                                        .add(questionObjectI.getNum());
                                                identicalMap100.get(questionI).add(questionObjectJ.getNum());
                                            } else if (similarity >= 90.0) {
                                                // 90%相似度
                                                identicalMap90.computeIfAbsent(questionI, k -> ConcurrentHashMap.newKeySet())
                                                        .add(questionObjectI.getNum());
                                                identicalMap90.get(questionI).add(questionObjectJ.getNum());
                                            } else if (similarity >= 85.0) {
                                                // 85%相似度
                                                identicalMap85.computeIfAbsent(questionI, k -> ConcurrentHashMap.newKeySet())
                                                        .add(questionObjectI.getNum());
                                                identicalMap85.get(questionI).add(questionObjectJ.getNum());
                                            }
                                        } finally {
                                            lock.unlock(); // 释放锁
                                        }
                                    }
                                }
                            }
                        }
                    }
                });

                // 输出完全相同的题干的序号
                identicalMap85.forEach((question, nums) -> {
                    if (nums.size() > 1) {
                        System.out.println("相似度85%题干:" + question + " 出现序号为 " + nums);
                        getDuplicateDetails("85%",nums, map, allDuplicateDetails);

                    }
                });

                // 输出完全相同的题干的序号
                identicalMap90.forEach((question, nums) -> {
                    if (nums.size() > 1) {
                        System.out.println("相似度90%题干:" + question + " 出现序号为 " + nums);
                        getDuplicateDetails("90%",nums, map, allDuplicateDetails);

                    }
                });

                // 输出完全相同的题干的序号
                identicalMap100.forEach((question, nums) -> {
                    if (nums.size() > 1) {
                        System.out.println("相似度100%题干:" + question + " 出现序号为 " + nums);
                        getDuplicateDetails("100%",nums, map, allDuplicateDetails);

                    }
                });

                //出题统计文档deplicateDetailsNew1.ftl
                String statistics = "winWord.ftl";
                //allDuplicateDetails进行排序不同的工种放一起
                Collections.sort(allDuplicateDetails.getDuplicateDetails(), new Comparator<DuplicateDetails>() {
                    @Override
                    public int compare(DuplicateDetails o1, DuplicateDetails o2) {
                        return o1.getWorkType().compareTo(o2.getWorkType());
                    }
                });
                int size = duplicateDetailsList.size();
                int chunkSize = 300; // 每个子列表的大小
                int numChunks = (size + chunkSize - 1) / chunkSize; // 计算需要生成的文档数量

                for (int i = 0; i < numChunks; i++) {
                    // 计算子列表的开始和结束索引
                    int start = i * chunkSize;
                    int end = Math.min(start + chunkSize, size);
                    //打印start end


                    // 创建子列表
                    List<DuplicateDetails> subList = duplicateDetailsList.subList(start, end);
                    //如果start end等于3301到3600打印数据subList
//                    if (start==3600){
//
//                        for (DuplicateDetails duplicateDetails : subList) {
//                            //打印序号
//
//
//                            //判断每个数据是否存在数据
//                            if (duplicateDetails.getWorkType()==null){
//                                System.err.println("工种:"+duplicateDetails.getWorkType());
//                            }
//                            if (duplicateDetails.getFileName()==null){
//                                System.err.println("文件名称:"+duplicateDetails.getFileName());
//                            }
//                            if (duplicateDetails.getSimilarity()==null){
//                                System.err.println("相似度:"+duplicateDetails.getSimilarity());
//                            }
//                            if (duplicateDetails.getDuplicateSet()==null){
//                                System.err.println("重复集合:"+duplicateDetails.getDuplicateSet());
//                            }
//                            if (duplicateDetails.getDuplicateNum()==null){
//                                System.err.println("重复序号:"+duplicateDetails.getDuplicateNum());
//                            }
//                            if (duplicateDetails.getDuplicateQuestionContent()==null){
//                                System.err.println("重复题干:"+duplicateDetails.getDuplicateQuestionContent());
//                            }
//                            if (duplicateDetails.getAnswer()==null){
//                                System.err.println("答案:"+duplicateDetails.getAnswer());
//                            }
//                            if (duplicateDetails.getOptionA()==null){
//                                System.err.println("选项A:"+duplicateDetails.getOptionA());
//                            }
//                            if (duplicateDetails.getOptionB()==null){
//                                System.err.println("选项B:"+duplicateDetails.getOptionB());
//                            }
//                            if (duplicateDetails.getOptionC()==null){
//                                System.err.println("选项C:"+duplicateDetails.getOptionC());
//                            }
//                            if (duplicateDetails.getOptionD()==null){
//                                System.err.println("选项D:"+duplicateDetails.getOptionD());
//                            }
//
//                        }
////
//
//                    }

                    // 创建新的AllDuplicateDetails对象，用于当前子列表
                    AllDuplicateDetails subAllDuplicateDetails = new AllDuplicateDetails();
                    subAllDuplicateDetails.setDuplicateDetails(subList);

                    // 将对象转换为Map，以便与FreeMarker模板兼容
                    Map<String, Object> dataModel = WordUtil.ObjectToMap(subAllDuplicateDetails);

                    // 生成文档的文件名
                    String newFileName = "查重结果_" + (i + 1) + ".docx";

                    // 调用工具类生成Word文档
//                    WordUtil.exportMillCertificateWord(request, response, dataModel, statistics, newFileName, resultPath+newFileName);
                    FileUtils.freemarkerExport(statistics, dataModel, resultPath , newFileName,response);
                }
            }
        }).sheet().doRead();
        return JsonResult.ok("导入成功");
    }

    public void newProcessQuestionData(QuestionData data, Map<String, Set<String>> errData, List questionDataList) {
        questionDataList.add(data);
        // 检查除了id之外的所有字段是否有为空的情况
        ValidationResult dataVal = isDataVal(data);
        if (dataVal.isValid()) {

        } else {
            if (data.getNum()!=null) {

                System.err.println(dataVal.getErrorMessage());
                // 如果有字段为空，则将数据的序号加入到错误数据集中
                errData.computeIfAbsent(data.getQuestionBankName(), k -> ConcurrentHashMap.newKeySet())
                        .add(data.getNum());
            }

        }
    }



//    @GetMapping("/checkTopic")
//    public JsonResult checkTopic1(String fileName,@Ignore HttpServletResponse response, @Ignore HttpServletRequest request) {
//        log.info("开始处理【查重】:{}", fileName);
//        File file = new File(fileName);
//        // 检查路径是否存在并且是否是一个文件
//        if (!file.exists() || !file.isFile()) {
//            throw new ServiceException(ServiceCode.OPERATION_FAILED, "文件不存在或不是一个有效文件");
//        }
//        // 检查文件是否为 .xlsx 文件
//        if (!fileName.toLowerCase().endsWith(".xlsx")) {
//            throw new ServiceException(ServiceCode.OPERATION_FAILED, "文件格式错误");
//        }
//        //库名称
//        String dbName = file.getName();
//        log.info("dbName:{}", dbName);
////        String fileName = "D:\\桌面\\wenjian\\bigtopic.xlsx"; // 替换为您的文件路径
//        List<QuestionData> questionDataList = new ArrayList<>();
//        Map<String, QuestionData> map = new HashMap<>();
//        EasyExcel.read(fileName, QuestionData.class, new AnalysisEventListener<QuestionData>() {
//            @Override
//            public void invoke(QuestionData data, AnalysisContext context) {
//                // 这里处理每行读取到的数据
//                // 遍历QuestionData的所有字段，去除字符串字段的空格
//
//                for (Field field : QuestionData.class.getDeclaredFields()) {
//                    field.setAccessible(true); // 确保可以访问私有字段
//                    try {
//                        if (field.get(data) instanceof String) {
//                            String value = (String) field.get(data);
//                            // 仅去除首尾空格
//                            value = value.trim();
//                            field.set(data, value);
//                        }
//                    } catch (IllegalAccessException e) {
//                        e.printStackTrace();
//                    }
//                }
//                //设置题库名称
//                data.setQuestionBankName(dbName);
//                questionDataList.add(data);
//                log.info("data:{}", data);
//                //如果存在
//                map.put(data.getNum(), data);
//            }
//            @SneakyThrows
//            @Override
//            public void doAfterAllAnalysed(AnalysisContext context) {
//                // 所有数据解析完成后做的事情
//                log.info("所有数据解析完成", questionDataList);
//                Map<String, Set<String>> identicalMap100 = new ConcurrentHashMap<>(); // 100%相似度
//                Map<String, Set<String>> identicalMap90 = new ConcurrentHashMap<>(); // 90%相似度
//                Map<String, Set<String>> identicalMap85  = new ConcurrentHashMap<>();
//                Set<Integer> checkedForIdentical = ConcurrentHashMap.newKeySet(); // 用于存储已经检查过的题干索引
//                AllDuplicateDetails allDuplicateDetails = new AllDuplicateDetails();
//                List<DuplicateDetails> duplicateDetailsList = new ArrayList<>();
//                allDuplicateDetails.setDuplicateDetails(duplicateDetailsList);
//
//                IntStream.range(0, questionDataList.size()).parallel().forEach(i -> {
//                    if (checkedForIdentical.contains(i)) return; // 如果这个题干已经标记为完全相同，则跳过
//
//                    QuestionData questionObjectI = questionDataList.get(i);
//                    if (questionObjectI != null) {
//                        String questionI = questionObjectI.getQuestionContent();
//                        if (questionI != null) {
//                            for (int j = i + 1; j < questionDataList.size(); j++) {
//                                if (checkedForIdentical.contains(j)) continue; // 跳过已经标记为完全相同的题干
//
//                                QuestionData questionObjectJ = questionDataList.get(j);
//                                if (questionObjectJ != null) {
//                                    String questionJ = questionObjectJ.getQuestionContent();
//                                    if (questionJ != null) {
//                                        double similarity = Levenshtein.calculateSimilarity(questionI, questionJ);
//                                        if (similarity == 100.0) {
//                                            // 100%相似度
//                                            identicalMap100.computeIfAbsent(questionI, k -> ConcurrentHashMap.newKeySet())
//                                                    .add(questionObjectI.getNum());
//                                            identicalMap100.get(questionI).add(questionObjectJ.getNum());
//                                        } else if (similarity >= 90.0) {
//                                            // 90%相似度
//                                            identicalMap90.computeIfAbsent(questionI, k -> ConcurrentHashMap.newKeySet())
//                                                    .add(questionObjectI.getNum());
//                                            identicalMap90.get(questionI).add(questionObjectJ.getNum());
//                                        } else if (similarity >= 85.0) {
//                                            // 85%相似度
//                                            identicalMap85.computeIfAbsent(questionI, k -> ConcurrentHashMap.newKeySet())
//                                                    .add(questionObjectI.getNum());
//                                            identicalMap85.get(questionI).add(questionObjectJ.getNum());
//                                        }
//                                    }
//                                }
//                            }
//                        }
//                    }
//                });
//
//                // 输出完全相同的题干的序号
//                identicalMap85.forEach((question, nums) -> {
//                    if (nums.size() > 1) {
//                        System.out.println("相似度85%题干:" + question + " 出现序号为 " + nums);
//                        getDuplicateDetails("85%",nums, map, allDuplicateDetails);
//
//                    }
//                });
//
//                // 输出完全相同的题干的序号
//                identicalMap90.forEach((question, nums) -> {
//                    if (nums.size() > 1) {
//                        System.out.println("相似度90%题干:" + question + " 出现序号为 " + nums);
//                        getDuplicateDetails("90%",nums, map, allDuplicateDetails);
//
//                    }
//                });
//
//                // 输出完全相同的题干的序号
//                identicalMap100.forEach((question, nums) -> {
//                    if (nums.size() > 1) {
//                        System.out.println("相似度100%题干:" + question + " 出现序号为 " + nums);
//                        getDuplicateDetails("100%",nums, map, allDuplicateDetails);
//
//                    }
//                });
//
//                //出题统计文档deplicateDetailsNew1.ftl
//                String statistics = "winWord.ftl";
//                //allDuplicateDetails进行排序不同的工种放一起
//                Collections.sort(allDuplicateDetails.getDuplicateDetails(), new Comparator<DuplicateDetails>() {
//                    @Override
//                    public int compare(DuplicateDetails o1, DuplicateDetails o2) {
//                        return o1.getWorkType().compareTo(o2.getWorkType());
//                    }
//                });
//
//
//                int size = duplicateDetailsList.size();
//                int chunkSize = 300; // 每个子列表的大小
//                int numChunks = (size + chunkSize - 1) / chunkSize; // 计算需要生成的文档数量
//
//                for (int i = 0; i < numChunks; i++) {
//                    // 计算子列表的开始和结束索引
//                    int start = i * chunkSize;
//                    int end = Math.min(start + chunkSize, size);
//                    //打印start end
//                    System.err.println("start:"+start+"end:"+end);
//
//                    // 创建子列表
//                    List<DuplicateDetails> subList = duplicateDetailsList.subList(start, end);
//                    //如果start end等于3301到3600打印数据subList
//                    if (start==3600){
//
//                        for (DuplicateDetails duplicateDetails : subList) {
//                            //打印序号
//
//
//                            //判断每个数据是否存在数据
//                            if (duplicateDetails.getWorkType()==null){
//                                System.err.println("工种:"+duplicateDetails.getWorkType());
//                            }
//                            if (duplicateDetails.getFileName()==null){
//                                System.err.println("文件名称:"+duplicateDetails.getFileName());
//                            }
//                            if (duplicateDetails.getSimilarity()==null){
//                                System.err.println("相似度:"+duplicateDetails.getSimilarity());
//                            }
//                            if (duplicateDetails.getDuplicateSet()==null){
//                                System.err.println("重复集合:"+duplicateDetails.getDuplicateSet());
//                            }
//                            if (duplicateDetails.getDuplicateNum()==null){
//                                System.err.println("重复序号:"+duplicateDetails.getDuplicateNum());
//                            }
//                            if (duplicateDetails.getDuplicateQuestionContent()==null){
//                                System.err.println("重复题干:"+duplicateDetails.getDuplicateQuestionContent());
//                            }
//                            if (duplicateDetails.getAnswer()==null){
//                                System.err.println("答案:"+duplicateDetails.getAnswer());
//                            }
//                            if (duplicateDetails.getOptionA()==null){
//                                System.err.println("选项A:"+duplicateDetails.getOptionA());
//                            }
//                            if (duplicateDetails.getOptionB()==null){
//                                System.err.println("选项B:"+duplicateDetails.getOptionB());
//                            }
//                            if (duplicateDetails.getOptionC()==null){
//                                System.err.println("选项C:"+duplicateDetails.getOptionC());
//                            }
//                            if (duplicateDetails.getOptionD()==null){
//                                System.err.println("选项D:"+duplicateDetails.getOptionD());
//                            }
//
//                        }
////
//
//                    }
//
//                    // 创建新的AllDuplicateDetails对象，用于当前子列表
//                    AllDuplicateDetails subAllDuplicateDetails = new AllDuplicateDetails();
//                    subAllDuplicateDetails.setDuplicateDetails(subList);
//
//                    // 将对象转换为Map，以便与FreeMarker模板兼容
//                    Map<String, Object> dataModel = WordUtil.ObjectToMap(subAllDuplicateDetails);
//
//                    // 生成文档的文件名
//                    String newFileName = "查重结果_" + (i + 1) + ".docx";
//
//                    // 调用工具类生成Word文档
//                    WordUtil.exportMillCertificateWord(request, response, dataModel, statistics, newFileName, "result");
//                }
//
////
////                Map<String, Object> dataModel =  WordUtil.ObjectToMap(allDuplicateDetails);
////                System.err.println(allDuplicateDetails.getDuplicateDetails().size());
////                WordUtil.exportMillCertificateWord(request, response, dataModel, statistics, fileName, name);
//            }
//        }).sheet().doRead();
//        return JsonResult.ok("导入成功");
//    }



    public static void getDuplicateDetails(String similarity,Set<String> nums, Map<String, QuestionData> map,AllDuplicateDetails allDuplicateDetails){

        for (String num : nums) {
            QuestionData questionData = map.get(num);
            if (questionData == null) {
                continue;
            };
            DuplicateDetails duplicateDetails = new DuplicateDetails();
            //设置相似度
            duplicateDetails.setSimilarity(similarity);
            //设置题库工种
            duplicateDetails.setWorkType(questionData.getWorkType());
            //设置题库名称
            duplicateDetails.setFileName(questionData.getQuestionBankName());
            duplicateDetails.setAnswer(questionData.getQuestionAnswer());
            //设置题库序号
            //判断nums是第几个如果num是第一个插入数据
            if (num.equals(nums.iterator().next())){
                duplicateDetails.setDuplicateSet(nums.toString());
            }
            //设置序号
            duplicateDetails.setDuplicateNum(num);
            //设置内容
            duplicateDetails.setDuplicateQuestionContent(questionData.getQuestionContent());
            //设置选项
            if (questionData.getQuestionOptions() != null) {
                String[] questionOptions = questionData.getQuestionOptions().split("\\$;\\$");
                //如果questionOptions.length不等于4，跳过这个题目
                if (questionOptions.length != 4) {
//                    throw new ServiceException(ServiceCode.OPERATION_FAILED, "请检查工种为【"+questionData.getWorkType()+"】，" +
//                            "序号为【"+questionData.getNum()+"】的题目选项是否有$$");
                    continue;
                }
                duplicateDetails.setOptionA(questionOptions[0]);
                duplicateDetails.setOptionB(questionOptions[1]);
                duplicateDetails.setOptionC(questionOptions[2]);
                duplicateDetails.setOptionD(questionOptions[3]);
            }
            allDuplicateDetails.getDuplicateDetails().add(duplicateDetails);
        }
    }

    @GetMapping("/delTopic")
    public JsonResult delTopic() {
        log.info("开始处理【删除所有题目】");
        topicMapper.truncateTable();
        return JsonResult.ok("清理成功！！！");
    }

    @PostMapping("/selectTopicNum")
    public JsonResult getSelectTopicNum(@RequestBody SelectTopicNumParam selectTopicNumParam) {
        log.info("开始处理【查询试题数量】:{}", selectTopicNumParam);
        QueryWrapper<QuestionData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("work_type", selectTopicNumParam.getWorkType());
        queryWrapper.eq("evaluation_level", selectTopicNumParam.getEvaluationLevel());
        queryWrapper.eq("question_type", selectTopicNumParam.getTypeList().getQuestionType());
        queryWrapper.eq("question_attribute", selectTopicNumParam.getTypeList().getQuestionAttribute());
        queryWrapper.eq("difficulty_level", selectTopicNumParam.getTypeList().getDifficultyLevel());
        Integer integer = topicMapper.selectCount(queryWrapper);
        return JsonResult.ok(integer);
    }

    @GetMapping("/isTopic")
    public JsonResult IsTopic(String workType, String evaluationLevel) {
        log.info("开始处理【查询是否存在题目】:工种{},等级：{}", workType,evaluationLevel);
        QueryWrapper<QuestionData> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("work_type", workType);
        queryWrapper.eq("evaluation_level", evaluationLevel);
        Integer integer = topicMapper.selectCount(queryWrapper);
        if (integer == 0) {
            throw new ServiceException(ServiceCode.OPERATION_FAILED,"不存在该工种或者等级的题目");
        }
        log.info("查询结果：{}", integer);
        return JsonResult.ok(integer);
    }




}
